#pragma once
#include <string>
#include <cstdint>
#include <unistd.h>

class I2CDevice {
public:
    /**
     * @brief Constructs an I2CDevice object with the specified device path and address.
     *
     * @param devicePath The path to the I2C device, e.g. "/dev/i2c-1".
     * @param address The 7-bit I2C address of the device.
     * 
     * @throw std::runtime_error If the device cannot be opened or the address cannot be set.
     */
    I2CDevice(const std::string& devicePath, uint8_t address);

    /**
     * @brief Destructor for the I2CDevice object.
     *
     * Closes the file descriptor associated with the I2C device when the object is destroyed.
     */
    ~I2CDevice();

    /**
     * @brief Writes a single byte to the specified register of the I2C device.
     *
     * @param reg The 8-bit register address to write to.
     * @param data The 8-bit data to write to the register.
     *
     * @return true if the write was successful, false otherwise.
     */
    bool writeByte(uint8_t reg, uint8_t data);

    /**
     * @brief Reads multiple bytes from the specified register of the I2C device.
     *
     * @param reg The 8-bit register address to read from.
     * @param buffer A pointer to a buffer where the data will be stored.
     * @param length The number of bytes to read.
     *
     * @return true if the read was successful, false otherwise.
     */
    bool readBytes(uint8_t reg, uint8_t* buffer, size_t length);


    /**
     * @brief Closes the file descriptor associated with the I2C device.
     *
     * This function is called by the destructor to ensure that the file descriptor
     * is properly closed when the object is destroyed.
     */
    void close();

private:
    int fd; /*!< The file descriptor for the I2C device. */
    uint8_t addr; /*!< The 7-bit address of the I2C device. */
};
